package com.xisoft.entity;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Author xzh
 * @Date 2021/8/12 16:26
 * @Description所有实体父类
 * @Version 1.0
 **/
public abstract class ZSuperEntityVo implements Serializable, Cloneable
{
    /************************************************************* <br>
     *
     *说明: 获取主键<br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:20  <br>
     * @param  </br>
     * @return java.lang.String  <br>
     * @Author xisoft
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static String getPrimaryKey( )
    {
        return "";
    }

    /************************************************************* <br>
     *
     *说明:获取表名 <br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:20  <br>
     * @param  </br>
     * @return java.lang.String  <br>
     * @Author xisoft
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static String getTableName( )
    {
        return "";
    }

    /************************************************************* <br>
     *
     *说明: 获取所有的属性<br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:19  <br>
     * @param  </br>
     * @return java.lang.String[]  <br>
     * @Author xisoft
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static String[] getColumns( )
    {
        return new String[]{};
    }

    /************************************************************* <br>
     *
     *说明: 通用的set方法<br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:18  <br>
     * @param propertyName
     * @param propertyValue <br>
     * @return void  <br>
     * @Author LIBENCHENG
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public void set(String propertyName, Object propertyValue) throws NoSuchFieldException, IllegalAccessException
    {
        Field field = this.getClass().getDeclaredField(propertyName);
        //setAccessible这行代码把对象上的propertyName字段设置为public访问属性.
        field.setAccessible(true);
        // 设置该对象的propertyValue属性
        field.set(this, propertyValue);
    }

    /************************************************************* <br>
     *
     *说明: 通用的get<br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:17  <br>
     * @param propertyName <br>
     * @return java.lang.Object  <br>
     * @Author xisoft
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public Object get(String propertyName) throws IntrospectionException, InvocationTargetException,
            IllegalAccessException
    {
        // 获取该对象的Class,获取所有的属性数组
        BeanInfo beanInfo = Introspector.getBeanInfo(this.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor property : propertyDescriptors)
        {
            String key = property.getName();
            // 过滤class属性
            if (!(key.equals("class") || key.equals("Class")))
            {
                // 得到property对应的getter方法
                Method getter = property.getReadMethod();
                //获取属性对应的 value
                if (key.equals(propertyName))
                {
                    return getter.invoke(this);
                }
            }
        }

        return null;
    }

    /************************************************************* <br>
     *
     *说明: <br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  15:28  <br>
     * @param obj <br>
     * @return java.util.Map<java.lang.String, java.lang.Object>  <br>
     * @Author LIBENCHENG
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public static Map< String,Object > transBean2Map(Object obj) throws Exception
    {
        if (null == obj)
        {
            return null;
        }
        Map< String,Object > map = new LinkedHashMap< String,Object >();
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        for (PropertyDescriptor property : propertyDescriptors)
        {
            String key = property.getName();
            // 过滤class属性
            if (!(key.equals("class") || key.equals("Class")))
            {
                Method getter = property.getReadMethod();
                if (null != getter)
                {
                    Object value = getter.invoke(obj);
                    map.put(key, value);
                }
            }
        }
        return map;
    }

    /************************************************************* <br>
     *
     *说明: 比较内容<br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:16  <br>
     * @param obj <br>
     * @return boolean  <br>
     * @Author xisoft
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public boolean equalsContent(Object obj) throws IntrospectionException, InvocationTargetException,
            IllegalAccessException
    {
        if (obj == this)
        {
            return true;
        }
        else if (obj == null)
        {
            return false;
        }
        else
        {
            return obj.getClass() == this.getClass() && this.equalsContent((ZSuperEntityVo) obj, getColumns());
        }
    }

    /************************************************************* <br>
     *
     *说明: 比较内容<br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:16  <br>
     * @param vo
     * @param columns <br>
     * @return boolean  <br>
     * @Author xisoft
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    public boolean equalsContent(ZSuperEntityVo vo, String[] columns) throws IntrospectionException,
            InvocationTargetException, IllegalAccessException
    {
        if (columns != null && vo != null)
        {
            int x = columns.length;
            for (int i = 0; i < (null == columns ? 0 : columns.length); ++i)
            {
                String attribute = columns[i];
                Object value1 = this.get(attribute);
                Object value2 = vo.get(attribute);
                boolean flag = this.isAttributeEquals(value1, value2);
                if (!flag)
                {
                    return false;
                }
            }
            return true;
        }
        else
        {
            return false;
        }
    }

    /************************************************************* <br>
     *
     *说明: 判断两个对象是不是同一个<br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:52  <br>
     * @param objOld
     * @param objNew <br>
     * @return boolean  <br>
     * @Author LIBENCHENG
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    private boolean isAttributeEquals(Object objOld, Object objNew)
    {
        if (objOld == objNew)
        { return true; }
        else
        { return objOld != null && objOld.equals(objNew); }
        
    }

    /************************************************************* <br>
     *
     *说明: 重写clone方法<br>
     *
     * @Description   <br>
     * @Date Created on 2021/12/6  14:52  <br>
     * @param  </br>
     * @return java.lang.Object  <br>
     * @Author LIBENCHENG
     * @version 1.0 <br>
     ************************************************************* <br>
     */
    @Override
    public Object clone( ) throws CloneNotSupportedException
    {
        ZSuperEntityVo vo = (ZSuperEntityVo) super.clone();
        String[] columns = getColumns();

        for (int i = 0; i < (null == columns ? 0 : columns.length); i++)
        {
            try
            {
                String column = columns[i];
                Object value = this.get(column);
                vo.set(column, value);
            }
            catch (NoSuchFieldException | IntrospectionException | InvocationTargetException | IllegalAccessException e)
            {
                throw new RuntimeException("conle() exception：" + e.getMessage());
            }
        }

        return vo;
    }

    @Override
    public String toString( )
    {
        return super.toString();
    }

}
